package org.colin.Tools;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.colin.model.bean.LawerLetter;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.WordprocessingML.AlternativeFormatInputPart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.org.apache.poi.util.IOUtils;
import org.docx4j.relationships.Relationship;
import org.docx4j.wml.CTAltChunk;
import org.springframework.stereotype.Component;
import com.aspose.words.Document;
import com.deepoove.poi.XWPFTemplate;
import lombok.extern.slf4j.Slf4j;

/**
 * @desc word文档工具类
 * @author wujiangbo
 * @date 2020年1月4日 上午10:00:11
 */
@Component
@Slf4j
public class DocxUtil {

	/**
	 * @desc 将word文件转换成PDF文件
	 * @author wujiangbo
	 * @date 2020年1月10日 下午1:43:25
	 * @param docFile word文件路径
	 * @param pdfFile pdf文件路径
	 */
	public void doc2Pdf(String docFile, String pdfFile) {
		log.info("DocxUtil(doc2Pdf)——docFile:{}", docFile);
		log.info("DocxUtil(doc2Pdf)——pdfFile:{}", pdfFile);
		try {
			long time1 = System.currentTimeMillis();
			// doc路径
			Document document = new Document(docFile);
			// pdf路径
			File outputFile = new File(pdfFile);
			// 操作文档保存
			document.save(outputFile.getAbsolutePath(), com.aspose.words.SaveFormat.PDF);
			long time2 = System.currentTimeMillis();
			log.info("DocxUtil(doc2Pdf)——word文件转换成PDF文件完成，耗时{}秒", (time2 - time1) / 1000);
		} catch (Exception e) {
			log.error("DocxUtil(doc2Pdf)——word文件转换成PDF文件——异常：{}", e);
		}
	}

	/**
	 * @desc 将多个word文档合并成一个文档
	 * @author wujiangbo
	 * @date 2019年12月12日 上午11:38:39
	 * @param list     需要合并文件的路径集合
	 * @param filePath 合并之后的存储路径
	 * @param fileName 合并之后的文件名
	 */
	public void mergeManyDocx(List<String> list, String filePath, String fileName) {
		log.info("mergeManyDocx-filePath={}", filePath);
		log.info("list.size()={}", list.size());
		log.info("mergeManyDocx-全路径={}", (filePath + File.separator + fileName));
		File f = new File(filePath);
		if (!f.exists()) {
			f.mkdirs();
		}
		long i1 = System.currentTimeMillis();
		try {
			List<InputStream> streams = new ArrayList<InputStream>();
			for (int i = 0; i < list.size(); i++) {
				streams.add(new FileInputStream(list.get(i)));
			}
			InputStream stream = mergeDocx(streams);
			saveFile(IOUtils.toByteArray(stream), filePath + File.separator + fileName);
			long i2 = System.currentTimeMillis();
			String msg = "将" + list.size() + "个word文档合并成一个文档----成功，总耗时：{}秒";
			log.info(msg, (i2 - i1) / 1000);
		} catch (Exception e) {
			log.error("将多个word文档合并成一个文档---异常--mergeManyDocx：{}", e);
		}
	}

	public void saveFile(byte[] bfile, String filePath) {
		BufferedOutputStream bos = null;
		FileOutputStream fos = null;
		File file = null;
		try {
			file = new File(filePath);
			fos = new FileOutputStream(file);
			bos = new BufferedOutputStream(fos);
			bos.write(bfile);
		} catch (Exception e) {
			log.error("发生异常----saveFile：{}", e);
		} finally {
			if (bos != null) {
				try {
					bos.close();
				} catch (IOException e1) {
					log.error("发生异常----saveFile-bos：{}", e1);
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e1) {
					log.error("发生异常----saveFile-fos：{}", e1);
				}
			}
		}
	}

	public InputStream mergeDocx(final List<InputStream> streams) throws Docx4JException, IOException {
		WordprocessingMLPackage target = null;
		final File generated = File.createTempFile("generated", ".docx");
		int chunkId = 0;
		Iterator<InputStream> it = streams.iterator();
		while (it.hasNext()) {
			InputStream is = it.next();
			if (is != null) {
				if (target == null) {
					// Copy first (master) document
					OutputStream os = new FileOutputStream(generated);
					os.write(IOUtils.toByteArray(is));
					os.close();

					target = WordprocessingMLPackage.load(generated);
				} else {
					// Attach the others (Alternative input parts)
					insertDocx(target.getMainDocumentPart(), IOUtils.toByteArray(is), chunkId++);
				}
			}
		}
		if (target != null) {
			target.save(generated);
			return new FileInputStream(generated);
		} else {
			return null;
		}
	}

	// 插入文档
	private void insertDocx(MainDocumentPart main, byte[] bytes, int chunkId) {
		try {
			AlternativeFormatInputPart afiPart = new AlternativeFormatInputPart(new PartName("/part" + chunkId + ".docx"));
			afiPart.setBinaryData(bytes);
			Relationship altChunkRel = main.addTargetPart(afiPart);
			CTAltChunk chunk = Context.getWmlObjectFactory().createCTAltChunk();
			chunk.setId(altChunkRel.getId());
			main.addObject(chunk);
		} catch (Exception e) {
			log.error("发生异常----insertDocx：{}", e);
		}
	}

	/**
	 * @desc 根据律师函模板生成律师函Word文档
	 * @author wujiangbo
	 * @date 2019年11月27日 下午5:18:41
	 * @param source_file_path 模板文件地址
	 * @param obj              数据模型
	 * @param target_file_path 生成律师函文件地址保存地址
	 */
	public void createLawerWord(String source_file_path, LawerLetter obj, String target_file_path) {
		try {
			log.info("根据律师函模板生成律师函PDF文档——source_file_path={}", source_file_path);
			XWPFTemplate template = XWPFTemplate.compile(source_file_path).render(obj);
			FileOutputStream out = new FileOutputStream(target_file_path);
			template.write(out);
			template.close();
			out.flush();
			out.close();
		} catch (FileNotFoundException e) {
			log.error("根据律师函模板生成律师函PDF文档-----异常FileNotFoundException：{}", e);
		} catch (IOException e) {
			log.error("根据律师函模板生成律师函PDF文档-----异常IOException：{}", e);
		}
	}
}
